home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / minigl.lha / MiniGL / src / context.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-06-02  |  40.0 KB  |  1,657 lines

  1. /*
  2.  * $Id: context.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
  3.  *
  4.  * $Date: 2000/04/07 19:44:51 $
  5.  * $Revision: 1.1.1.1 $
  6.  *
  7.  * (C) 1999 by Hyperion
  8.  * All rights reserved
  9.  *
  10.  * This file is part of the MiniGL library project
  11.  * See the file Licence.txt for more details
  12.  *
  13.  */
  14.  
  15.  
  16. #include "sysinc.h"
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21.  
  22. static char rcsid[] = "$Id: context.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
  23.  
  24.  
  25. extern void GLMatrixInit(GLcontext context);
  26. GLboolean MGLInitContext(GLcontext context);
  27.  
  28. #ifndef __PPC__
  29. extern struct IntuitionBase *IntuitionBase;
  30. extern struct ExecBase *SysBase;
  31. extern struct GfxBase *GfxBase;
  32. extern struct DosLibrary *DOSBase;
  33. #endif
  34.  
  35. GLcontext mini_CurrentContext;
  36.  
  37. #ifdef __PPC__
  38. extern struct Library *Warp3DPPCBase;
  39. #else
  40. extern struct Library *Warp3DBase;
  41. #endif
  42.  
  43. extern struct Library *CyberGfxBase;
  44.  
  45. extern void tex_FreeTextures(GLcontext context);
  46. extern void TMA_Start(LockTimeHandle *handle);
  47.  
  48. #ifndef NLOGGING
  49. int MGLDebugLevel;
  50. #endif
  51.  
  52. // Default values for new context
  53.  
  54. /*
  55. Surgeon: bumped newVertexBufferSizefrom 40 to 256 because of increased requirement for clipping space due to buffering
  56. */
  57.  
  58. static int newVertexBufferSize = 256;            // Default: 256 entries in vertex buffer
  59.  
  60. static int newTextureBufferSize = 2048;         // Default: 2048 texture objects
  61. static int newNumberOfBuffers = 2;              // Default: Double buffering
  62. static int newPixelDepth = 15;                  // Default: 15 bits per pixel
  63. static GLboolean newWindowMode = GL_FALSE;      // Default: Use fullscreen instead of window
  64. static GLboolean clw = GL_FALSE;                // Default: Keep workbench open
  65. static GLboolean newNoMipMapping = GL_TRUE;     // Default: No mipmapping
  66. static GLboolean newNoFallbackAlpha = GL_FALSE; // Default: Fall back to supported blend mode
  67. static GLboolean newGuardBand = GL_FALSE;      // Default: guardband clipping is off
  68.  
  69. static struct TagItem tags[7];
  70.  
  71. static UWORD *MousePointer = 0;
  72.  
  73. static GLboolean sys_MaybeOpenVidLibs(void)
  74. {
  75. #ifdef __PPC__
  76.     if (!Warp3DPPCBase)
  77.     {
  78.         Warp3DPPCBase = OpenLibrary("Warp3DPPC.library", 2L);
  79.         if (!Warp3DPPCBase)
  80.         {
  81.             printf("Error opening Warp3D library\n");
  82.             return GL_FALSE;
  83.         }
  84.     }
  85. #else
  86.     if (!Warp3DBase)
  87.     {
  88.         Warp3DBase = OpenLibrary("Warp3D.library", 2L);
  89.         if (!Warp3DBase)
  90.         {
  91.             printf("Error opening Warp3D library\n");
  92.             return GL_FALSE;
  93.         }
  94.     }
  95.  
  96. #endif
  97.  
  98.     if (!CyberGfxBase)
  99.     {
  100.         CyberGfxBase = OpenLibrary("cybergraphics.library", 0L);
  101.         if (!CyberGfxBase)
  102.         {
  103.             printf("Error opening cybergraphics.library\n");
  104.             return GL_FALSE;
  105.         }
  106.     }
  107.  
  108.     return GL_TRUE;
  109. }
  110.  
  111. static void vid_Pointer(struct Window *window)
  112. {
  113.     if (!MousePointer)
  114.     {
  115. #ifdef __PPC__
  116.         MousePointer = AllocVecPPC(8, MEMF_CLEAR|MEMF_CHIP|MEMF_PUBLIC,0); //OF (8 instead of 12, MEMF_PUBLIC)
  117. #else
  118.         MousePointer = AllocVec(8, MEMF_CLEAR|MEMF_CHIP|MEMF_PUBLIC); //OF (idem)
  119. #endif
  120.     }
  121.  
  122.     if (window)         SetPointer(window, MousePointer, 0, 0, 0, 0); //OF (was 1, 16, 0, 0)
  123. }
  124.  
  125. static void vid_DeletePointer(struct Window *window)
  126. {
  127.     if (window)         ClearPointer(window);
  128. #ifdef __PPC__
  129.     FreeVecPPC(MousePointer);
  130. #else
  131.     FreeVec(MousePointer);
  132. #endif
  133.     MousePointer = 0;
  134. }
  135.  
  136. void GLScissor(GLcontext context, GLint x, GLint y, GLsizei width, GLsizei height)
  137. {
  138.     //LOG(1, glScissor, "%d %d %d %d",x,y,width,height);
  139.  
  140.     if(context->Scissor_State == GL_TRUE)
  141.     {
  142.         static W3D_Scissor scissor;
  143.  
  144.         scissor.left = x;
  145.         scissor.top = context->w3dWindow->Height-y-height;
  146.         scissor.width = width;
  147.         scissor.height = height;
  148.  
  149.         W3D_SetScissor(context->w3dContext, &scissor);
  150.      }
  151.     else
  152.     {
  153.         context->scissor.left = x;
  154.         context->scissor.top = context->w3dWindow->Height-y-height;
  155.         context->scissor.width = width;
  156.         context->scissor.height = height;
  157.     }
  158. }
  159.  
  160. static void vid_CloseDisplay(GLcontext context)
  161. {
  162.     int i;
  163.  
  164.     if (context->w3dContext)
  165.     {
  166.         W3D_FreeZBuffer(context->w3dContext);
  167.         tex_FreeTextures(context);
  168.         W3D_DestroyContext(context->w3dContext);
  169.         context->w3dContext = 0;
  170.     }
  171.  
  172. #ifdef __PPC__
  173.     if (Warp3DPPCBase) CloseLibrary(Warp3DPPCBase);
  174.     Warp3DPPCBase = NULL;
  175. #else
  176.     if (Warp3DBase) CloseLibrary(Warp3DBase);
  177.     Warp3DBase = NULL;
  178. #endif
  179.  
  180.     Delay(25L);
  181.     if (context->Buffers[0])
  182.     {
  183.         context->Buffers[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  184.         while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[0]));
  185.     }
  186.  
  187.     for (i=0; i<context->NumBuffers; i++)
  188.     {
  189.         if (context->Buffers[i])
  190.             FreeScreenBuffer(context->w3dScreen, context->Buffers[i]);
  191.         context->Buffers[i] = NULL;
  192.     }
  193.  
  194.     vid_DeletePointer(context->w3dWindow);
  195.     if (context->w3dWindow) CloseWindow(context->w3dWindow);
  196.     if (context->w3dScreen) CloseScreen(context->w3dScreen);
  197.  
  198.     if (clw == GL_TRUE) OpenWorkBench();
  199. }
  200.  
  201. static GLboolean vid_ReopenDisplay(GLcontext context, int w, int h)
  202. {
  203.     ULONG ModeID, IDCMP;
  204.     int i;
  205.     struct TagItem BestModeTags[] =
  206.     {
  207.         {W3D_BMI_WIDTH,  0},
  208.         {W3D_BMI_HEIGHT, 0},
  209.         {W3D_BMI_DEPTH,  0},
  210.         {TAG_DONE,       0}
  211.     };
  212.  
  213.     struct TagItem OpenScrTags[] =
  214.     {
  215.         {SA_Height,      0},
  216.         {SA_Width,       0},
  217.         {SA_Depth,       8L},
  218.         {SA_DisplayID,   0},
  219.         {SA_ShowTitle,   FALSE},
  220.         {SA_Draggable,   FALSE},
  221.         {TAG_DONE,       0}
  222.     };
  223.  
  224.     struct TagItem OpenWinTags[] =
  225.     {
  226.         WA_CustomScreen,        0,
  227.         WA_Width,               0,
  228.         WA_Height,              0,
  229.         WA_Left,                0,
  230.         WA_Top,                 0,
  231.         WA_Title,               0,
  232.         WA_Flags,               WFLG_ACTIVATE|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE|WFLG_RMBTRAP,
  233.         WA_IDCMP,               0,
  234.         TAG_DONE,               0
  235.     };
  236.  
  237.     if (!context)
  238.         return GL_FALSE;
  239.  
  240.     #ifndef NCGXDEBUG
  241.     ULONG flag;
  242.  
  243.     if (GL_FALSE == sys_MaybeOpenVidLibs())
  244.     {
  245.         return GL_FALSE;
  246.     }
  247.     #endif
  248.  
  249.     if (context->Buffers[0])
  250.     {
  251.         context->Buffers[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  252.         while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[0]));
  253.     }
  254.  
  255.     for (i=0; i<context->NumBuffers; i++)
  256.     {
  257.         if (context->Buffers[i])
  258.             FreeScreenBuffer(context->w3dScreen, context->Buffers[i]);
  259.         context->Buffers[i] = NULL;
  260.     }
  261.  
  262.     IDCMP = context->w3dWindow->IDCMPFlags;
  263.  
  264.     if (context->w3dWindow) CloseWindow(context->w3dWindow); context->w3dWindow = NULL;
  265.     if (context->w3dScreen) CloseScreen(context->w3dScreen); context->w3dScreen = NULL;
  266.  
  267.     BestModeTags[0].ti_Data = (ULONG)w;
  268.     BestModeTags[1].ti_Data = (ULONG)h;
  269.     BestModeTags[2].ti_Data = (ULONG)newPixelDepth;
  270.  
  271.     ModeID = W3D_BestModeID(BestModeTags);
  272.  
  273.     if (ModeID == INVALID_ID) return GL_FALSE;
  274.  
  275.     OpenScrTags[0].ti_Data = (ULONG)w;
  276.     OpenScrTags[1].ti_Data = (ULONG)h;
  277.     OpenScrTags[3].ti_Data = ModeID;
  278.  
  279.     context->w3dScreen = OpenScreenTagList(NULL, OpenScrTags);
  280.  
  281.     if (!context->w3dScreen)
  282.     {
  283.         printf("Failed to re-open screen\n");
  284.         return GL_FALSE;
  285.     }
  286.  
  287.     OpenWinTags[0].ti_Data = (ULONG)context->w3dScreen;
  288.     OpenWinTags[1].ti_Data = (ULONG)context->w3dScreen->Width;
  289.     OpenWinTags[2].ti_Data = (ULONG)context->w3dScreen->Height;
  290.     OpenWinTags[7].ti_Data = IDCMP;
  291.  
  292.     context->w3dWindow = OpenWindowTagList(NULL, OpenWinTags);
  293.  
  294.     if (!context->w3dWindow)
  295.     {
  296.         printf("Failed to re-open window\n");
  297.         goto Duh;
  298.     }
  299.  
  300.     context->Buffers[0] = AllocScreenBuffer(context->w3dScreen, NULL, SB_SCREEN_BITMAP);
  301.  
  302.     if (!context->Buffers[0])
  303.     {
  304.         printf("Failed to allocate screen buffer\n");
  305.         goto Duh;
  306.     }
  307.  
  308.     #ifndef NCGXDEBUG
  309.     flag = GetCyberMapAttr(context->Buffers[0]->sb_BitMap, CYBRMATTR_ISCYBERGFX);
  310.  
  311.     if (!flag)
  312.         printf("Warning: No CyberGraphics bitmap in buffer 0\n");
  313.     else
  314.         printf("Info: Buffer 0 is a cybergraphics bitmap\n");
  315.     #endif
  316.  
  317.  
  318.     for (i=1; i<newNumberOfBuffers; i++)
  319.     {
  320.         context->Buffers[i] = AllocScreenBuffer(context->w3dScreen, NULL, 0);
  321.         if (!context->Buffers[i]) goto Duh;
  322.  
  323.         #ifndef NCGXDEBUG
  324.         flag = GetCyberMapAttr(context->Buffers[0]->sb_BitMap, CYBRMATTR_ISCYBERGFX);
  325.  
  326.         if (!flag)
  327.             printf("Warning: No CyberGraphics bitmap in buffer %d\n", i);
  328.         else
  329.             printf("Info: Buffer %d is a cybergraphics bitmap\n", i);
  330.         #endif
  331.     }
  332.  
  333.     context->BufNr      = 1;                    // The drawing buffer
  334.     SetRGB32(&(context->w3dScreen->ViewPort), 0, 0x7fffffff,0x7fffffff,0x7fffffff);
  335.  
  336.     for (i=0; i<context->NumBuffers; i++)
  337.     {
  338.         context->Buffers[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  339.         while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[i]));
  340.         EraseRect(context->w3dWindow->RPort, context->w3dWindow->BorderLeft,
  341.             context->w3dWindow->BorderTop,
  342.             context->w3dWindow->Width-context->w3dWindow->BorderLeft-context->w3dWindow->BorderRight-1,
  343.             context->w3dWindow->Height-context->w3dWindow->BorderTop-context->w3dWindow->BorderBottom-1);
  344.     }
  345.     context->Buffers[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  346.  
  347.     while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[0]));
  348.  
  349.  
  350.     GLScissor(context, 0, 0, w, h);
  351.  
  352.     W3D_SetDrawRegion(context->w3dContext, context->Buffers[1]->sb_BitMap,
  353.         0, &(context->scissor));
  354.  
  355.     //surgeon:
  356.     W3D_SetScissor(context->w3dContext, &(context->scissor));    
  357.  
  358.     W3D_FreeZBuffer(context->w3dContext);
  359.     W3D_AllocZBuffer(context->w3dContext);
  360.  
  361.     vid_Pointer(context->w3dWindow);
  362.                      
  363.     return GL_TRUE;
  364.  
  365. Duh:
  366.     printf("An error occured - closing down\n");
  367.     vid_CloseDisplay(context);
  368.  
  369.     return GL_FALSE;
  370. }
  371.  
  372. static GLboolean vid_OpenDisplay(GLcontext context, int pw, int ph, ULONG id)
  373. {
  374.     ULONG ModeID;
  375.     ULONG CError;
  376.     int i;
  377.     ULONG result;
  378.     #ifndef NCGXDEBUG
  379.     ULONG flag;
  380.     #endif
  381.     int w = 0, h = 0;
  382.  
  383.     struct TagItem BestModeTags[] =
  384.     {
  385.         {W3D_BMI_WIDTH,  0},
  386.         {W3D_BMI_HEIGHT, 0},
  387.         {W3D_BMI_DEPTH,  0},
  388.         {TAG_DONE,       0}
  389.     };
  390.  
  391.     struct TagItem OpenScrTags[] =
  392.     {
  393.         {SA_Depth,       8L},
  394.         {SA_DisplayID,   0},
  395.         {SA_ShowTitle,   FALSE},
  396.         {SA_Draggable,   FALSE},
  397.         {TAG_DONE,      0}
  398.     };
  399.  
  400.     struct TagItem OpenWinTags[] =
  401.     {
  402.         {WA_CustomScreen,        0},
  403.         {WA_Width,               0},
  404.         {WA_Height,              0},
  405.         {WA_Left,                0},
  406.         {WA_Top,                 0},
  407.         {WA_Title,               0},
  408.         {WA_Flags,               WFLG_ACTIVATE|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE|WFLG_RMBTRAP},
  409.         {TAG_DONE,               0}
  410.     };
  411.  
  412.     if (!context)
  413.         return GL_FALSE;
  414.  
  415.     if (GL_FALSE == sys_MaybeOpenVidLibs())
  416.         return GL_FALSE;
  417.  
  418.     if (id != MGL_SM_BESTMODE && id != MGL_SM_WINDOWMODE)
  419.     {
  420.         ModeID = id;
  421.     }
  422.     else
  423.     {
  424.         w = pw;
  425.         h = ph;
  426.         BestModeTags[0].ti_Data = (ULONG)w;
  427.         BestModeTags[1].ti_Data = (ULONG)h;
  428.         BestModeTags[2].ti_Data = (ULONG)newPixelDepth;
  429.  
  430.         ModeID = W3D_BestModeID(BestModeTags);
  431.     }
  432.  
  433.     if (clw == GL_TRUE)
  434.         CloseWorkBench();
  435.  
  436.     if (ModeID == INVALID_ID)
  437.         return GL_FALSE;
  438.  
  439.  
  440.     OpenScrTags[1].ti_Data = ModeID;
  441.  
  442.     context->w3dScreen = OpenScreenTagList(NULL, OpenScrTags);
  443.  
  444.  
  445.     if (context->w3dScreen && id != MGL_SM_BESTMODE)
  446.     {
  447.         w = context->w3dScreen->Width;
  448.         h = context->w3dScreen->Height;
  449.     }
  450.  
  451.     if (!context->w3dScreen) return GL_FALSE;
  452.  
  453.     // We don't include IDCMP flags. The user can change this with
  454.     // a call to ModifyIDCMP.
  455.  
  456.     OpenWinTags[0].ti_Data = (ULONG)context->w3dScreen;
  457.     OpenWinTags[1].ti_Data = (ULONG)context->w3dScreen->Width;
  458.     OpenWinTags[2].ti_Data = (ULONG)context->w3dScreen->Height;
  459.  
  460.     context->w3dWindow = OpenWindowTagList(NULL, OpenWinTags);
  461.  
  462.     if (!context->w3dWindow) goto Duh;
  463.  
  464.     context->Buffers[0] = AllocScreenBuffer(context->w3dScreen, NULL, SB_SCREEN_BITMAP);
  465.     if (!context->Buffers[0])
  466.     {
  467.         printf("Error: Can't create screen buffer 0\n");
  468.         goto Duh;
  469.     }
  470.  
  471.     #ifndef NCGXDEBUG
  472.     flag = GetCyberMapAttr(context->Buffers[0]->sb_BitMap, CYBRMATTR_ISCYBERGFX);
  473.  
  474.     if (!flag)
  475.         printf("Warning: No CyberGraphics bitmap in buffer 0\n");
  476.     else
  477.         printf("Info: Buffer 0 is a cybergraphics bitmap\n");
  478.     #endif
  479.  
  480.  
  481.     for (i=1; i<newNumberOfBuffers; i++)
  482.     {
  483.         context->Buffers[i] = AllocScreenBuffer(context->w3dScreen, NULL, 0);
  484.         if (!context->Buffers[i])
  485.         {
  486.             printf("Error: Can't create screen buffer %d\n", i);
  487.             goto Duh;
  488.         }
  489.         #ifndef NCGXDEBUG
  490.         flag = GetCyberMapAttr(context->Buffers[0]->sb_BitMap, CYBRMATTR_ISCYBERGFX);
  491.  
  492.         if (!flag)
  493.             printf("Warning: No CyberGraphics bitmap in buffer %d\n", i);
  494.         else
  495.             printf("Info: Buffer 0 is a cybergraphics bitmap\n");
  496.         #endif
  497.     }
  498.  
  499.     context->BufNr      = 1;                    // The drawing buffer
  500.     context->NumBuffers = newNumberOfBuffers;   // So we know the limit
  501.     context->DoSync     = GL_TRUE;              // Enable sync'ing
  502.  
  503.     tags[0].ti_Tag      = W3D_CC_MODEID;
  504.     tags[0].ti_Data     = ModeID;
  505.  
  506.     tags[1].ti_Tag      = W3D_CC_BITMAP;
  507.     tags[1].ti_Data     = (ULONG)(context->Buffers[1]->sb_BitMap);
  508.  
  509.     tags[2].ti_Tag      = W3D_CC_DRIVERTYPE;
  510.     tags[2].ti_Data     = W3D_DRIVER_BEST;
  511.  
  512.     tags[3].ti_Tag      = W3D_CC_FAST;
  513.     tags[3].ti_Data     = FALSE;
  514.  
  515.     tags[4].ti_Tag      = W3D_CC_YOFFSET;
  516.     tags[4].ti_Data     = 0;
  517.  
  518.     tags[5].ti_Tag      = W3D_CC_GLOBALTEXENV;
  519.     tags[5].ti_Data     = TRUE;
  520.  
  521.     tags[6].ti_Tag      = TAG_DONE;
  522.  
  523.     context->w3dContext = W3D_CreateContext(&CError, tags);
  524.  
  525.     if (!context->w3dContext || CError != W3D_SUCCESS)
  526.     {
  527.         switch(CError)
  528.         {
  529.             case W3D_ILLEGALINPUT:
  530.                     printf("Illegal input to CreateContext function\n");
  531.                     break;
  532.             case W3D_NOMEMORY:
  533.                     printf("Out of memory\n");
  534.                     break;
  535.             case W3D_NODRIVER:
  536.                     printf("No suitable driver found\n");
  537.                     break;
  538.             case W3D_UNSUPPORTEDFMT:
  539.                     printf("Supplied bitmap cannot be handled by Warp3D\n");
  540.                     break;
  541.             case W3D_ILLEGALBITMAP:
  542.                     printf("Supplied bitmap not properly initialized\n");
  543.                     break;
  544.             default:
  545.                     printf("An error has occured... gosh\n");
  546.         }
  547.         goto Duh;
  548.     }
  549.  
  550.     /*
  551.     ** Set up a few initial states
  552.     ** We always enable scissoring and dithering, since it looks better
  553.     ** on 16 bit displays.
  554.     ** We also set shading to smooth (Gouraud).
  555.     */
  556.     W3D_SetState(context->w3dContext, W3D_DITHERING,    W3D_ENABLE);
  557.     W3D_SetState(context->w3dContext, W3D_SCISSOR,      W3D_ENABLE);
  558.     W3D_SetState(context->w3dContext, W3D_GOURAUD,      W3D_ENABLE);
  559.     W3D_SetState(context->w3dContext, W3D_PERSPECTIVE,  W3D_ENABLE);
  560.  
  561.  
  562.     SetRGB32(&(context->w3dScreen->ViewPort), 0, 0x7fffffff,0x7fffffff,0x7fffffff);
  563.  
  564.  
  565.     /*
  566.     ** Allocate the ZBuffer.
  567.     */
  568.     result = W3D_AllocZBuffer(context->w3dContext);
  569.  
  570.     switch(result)
  571.     {
  572.         case W3D_NOGFXMEM:      printf("No ZBuffer: Memory shortage\n");            break;
  573.         case W3D_NOZBUFFER:     printf("No ZBuffer: Operation not supported\n");    break;
  574.         case W3D_NOTVISIBLE:    printf("No ZBuffer: Screen is not visible\n");      break;
  575.     }
  576.  
  577.  
  578.     W3D_SetState(context->w3dContext, W3D_ZBUFFER, W3D_DISABLE);
  579.     W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_ENABLE);
  580.     W3D_SetZCompareMode(context->w3dContext, W3D_Z_LESS);
  581.  
  582.  
  583.     for (i=0; i<context->NumBuffers; i++)
  584.     {
  585.         context->Buffers[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  586.         while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[i]));
  587.         EraseRect(context->w3dWindow->RPort, context->w3dWindow->BorderLeft,
  588.             context->w3dWindow->BorderTop,
  589.             context->w3dWindow->Width-context->w3dWindow->BorderLeft-context->w3dWindow->BorderRight-1,
  590.             context->w3dWindow->Height-context->w3dWindow->BorderTop-context->w3dWindow->BorderBottom-1);
  591.     }
  592.  
  593.     context->Buffers[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  594.     while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[0]));
  595.  
  596.     GLScissor(context, 0,0, w,h);
  597.  
  598.     //surgeon: added
  599.     W3D_SetDrawRegion(context->w3dContext, context->Buffers[1]->sb_BitMap,
  600.         0, &(context->scissor));
  601.  
  602.     W3D_SetScissor(context->w3dContext, &(context->scissor));    
  603.  
  604.     context->w3dLocked = GL_FALSE;
  605.  
  606.     /*
  607.     ** Select a texture format that needs no conversion
  608.     */
  609.     //FIXME:Really do it. This is lame
  610.     context->w3dFormat = W3D_R5G6B5;
  611.     context->w3dAlphaFormat = W3D_A4R4G4B4;
  612.     context->w3dBytesPerTexel = 2;
  613.  
  614.     vid_Pointer(context->w3dWindow); 
  615.                      
  616.     return GL_TRUE;
  617.  
  618. Duh:
  619.     for (i=0; i<newNumberOfBuffers; i++)
  620.     {
  621.         if (context->Buffers[i])
  622.         {
  623.             FreeScreenBuffer(context->w3dScreen, context->Buffers[i]);
  624.             context->Buffers[i] = NULL;
  625.         }
  626.     }
  627.  
  628.     if (context->w3dWindow)
  629.     {
  630.         CloseWindow(context->w3dWindow);
  631.         context->w3dWindow = NULL;
  632.     }
  633.  
  634.     if (context->w3dScreen)
  635.     {
  636.         CloseScreen(context->w3dScreen);
  637.         context->w3dScreen = NULL;
  638.     }
  639.  
  640.     return GL_FALSE;
  641. }
  642.  
  643. static void vid_CloseWindow(GLcontext context)
  644. {
  645.     if (!context)
  646.         return;
  647.  
  648.     if (context->w3dContext)
  649.     {
  650.         W3D_FreeZBuffer(context->w3dContext);
  651.         tex_FreeTextures(context);
  652.         W3D_DestroyContext(context->w3dContext);
  653.         context->w3dContext = 0;
  654.     }
  655.  
  656. #ifdef __PPC__
  657.     if (Warp3DPPCBase)          CloseLibrary(Warp3DPPCBase);
  658.     Warp3DPPCBase = NULL;
  659. #else
  660.     if (Warp3DBase)             CloseLibrary(Warp3DBase);
  661.     Warp3DBase = NULL;
  662. #endif
  663.  
  664.     if (context->w3dWindow)     CloseWindow(context->w3dWindow);
  665.     if (context->w3dScreen)     CloseScreen(context->w3dScreen);
  666.     if (context->w3dBitMap)     FreeBitMap(context->w3dBitMap);
  667.     if (context->w3dRastPort)   free(context->w3dRastPort);
  668. }
  669.  
  670.  
  671. static GLboolean vid_OpenWindow(GLcontext context, int w, int h)
  672. {
  673.     ULONG CError;
  674.     ULONG result;
  675.  
  676.     struct TagItem OpenWinTags[] =
  677.     {
  678.         {WA_PubScreen,           0},
  679.         {WA_InnerWidth,          0},
  680.         {WA_InnerHeight,         0},
  681.         {WA_Left,                30},
  682.         {WA_Top,                 30},
  683.         {WA_Title,               (ULONG)"MiniGL Display"},
  684.         {WA_DragBar,             TRUE},
  685.         {WA_DepthGadget,         TRUE},
  686.         {WA_Flags,               WFLG_ACTIVATE|WFLG_REPORTMOUSE|WFLG_RMBTRAP},
  687.         {TAG_DONE,               0}
  688.     };
  689.  
  690.     if (!context)
  691.         return GL_FALSE;
  692.  
  693.     if (GL_FALSE == sys_MaybeOpenVidLibs())
  694.     {
  695.         return GL_FALSE;
  696.     }
  697.  
  698.     context->w3dScreen = LockPubScreen(NULL);
  699.     if (!context->w3dScreen) return GL_FALSE;
  700.  
  701.     // We don't include IDCMP flags. The user can change this with
  702.     // a call to ModifyIDCMP.
  703.  
  704.     OpenWinTags[0].ti_Data = (ULONG)context->w3dScreen;
  705.     OpenWinTags[1].ti_Data = (ULONG)w;
  706.     OpenWinTags[2].ti_Data = (ULONG)h;
  707.  
  708.     context->w3dWindow = OpenWindowTagList(NULL, OpenWinTags);
  709.  
  710.     if (!context->w3dWindow) goto Duh;
  711.  
  712.     context->BufNr      = 0;                    // The drawing buffer
  713.     context->NumBuffers = 0;                    // Indicates we're using a window
  714.     context->DoSync     = GL_TRUE;              // Enable sync'ing
  715.  
  716.     context->w3dBitMap  = AllocBitMap(w,h,8,BMF_MINPLANES|BMF_DISPLAYABLE,
  717.         context->w3dWindow->RPort->BitMap);
  718.     if (!context->w3dBitMap) goto Duh;
  719.  
  720.     context->w3dRastPort = malloc(sizeof(struct RastPort));
  721.     if (!context->w3dRastPort)
  722.     {
  723.         printf("Error: unable to allocate rastport memory\n");
  724.         goto Duh;
  725.     }
  726.  
  727.     InitRastPort(context->w3dRastPort);
  728.     context->w3dRastPort->BitMap = context->w3dBitMap;
  729.  
  730.     tags[0].ti_Tag  = W3D_CC_BITMAP;
  731.     tags[0].ti_Data = (ULONG)(context->w3dBitMap);
  732.  
  733.     tags[1].ti_Tag  = W3D_CC_DRIVERTYPE;
  734.     tags[1].ti_Data = W3D_DRIVER_BEST;
  735.  
  736.     tags[2].ti_Tag  = W3D_CC_FAST;
  737.     tags[2].ti_Data = FALSE;
  738.  
  739.     tags[3].ti_Tag  = W3D_CC_YOFFSET;
  740.     tags[3].ti_Data = 0;
  741.  
  742.     tags[4].ti_Tag  = W3D_CC_GLOBALTEXENV;
  743.     tags[4].ti_Data = TRUE;
  744.  
  745.     tags[5].ti_Tag  = TAG_DONE;
  746.  
  747.     context->w3dContext = W3D_CreateContext(&CError, tags);
  748.     if (!context->w3dContext || CError != W3D_SUCCESS)
  749.     {
  750.         switch(CError)
  751.         {
  752.             case W3D_ILLEGALINPUT:
  753.                     printf("Illegal input to CreateContext function\n");
  754.                     break;
  755.             case W3D_NOMEMORY:
  756.                     printf("Out of memory\n");
  757.                     break;
  758.             case W3D_NODRIVER:
  759.                     printf("No suitable driver found\n");
  760.                     break;
  761.             case W3D_UNSUPPORTEDFMT:
  762.                     printf("Supplied bitmap cannot be handled by Warp3D\n");
  763.                     break;
  764.             case W3D_ILLEGALBITMAP:
  765.                     printf("Supplied bitmap not properly initialized\n");
  766.                     break;
  767.             default:
  768.                     printf("An error has occured... gosh\n");
  769.         }
  770.         goto Duh;
  771.     }
  772.     /*
  773.     ** Set up a few initial states
  774.     ** We always enable scissoring and dithering, since it looks better
  775.     ** on 16 bit displays.
  776.     ** We also set shading to smooth (Gouraud).
  777.     */
  778.     W3D_SetState(context->w3dContext, W3D_DITHERING,    W3D_ENABLE);
  779.     W3D_SetState(context->w3dContext, W3D_SCISSOR,      W3D_ENABLE);
  780.     W3D_SetState(context->w3dContext, W3D_GOURAUD,      W3D_ENABLE);
  781.     W3D_SetState(context->w3dContext, W3D_PERSPECTIVE,  W3D_ENABLE);
  782.  
  783.  
  784.     /*
  785.     ** Allocate the ZBuffer.
  786.     */
  787.     result = W3D_AllocZBuffer(context->w3dContext);
  788.     switch(result)
  789.     {
  790.         case W3D_NOGFXMEM:      printf("No ZBuffer: Memory shortage\n"); break;
  791.         case W3D_NOZBUFFER:     printf("No ZBuffer: Operation not supported\n"); break;
  792.         case W3D_NOTVISIBLE:    printf("No ZBuffer: Screen is not visible\n"); break;
  793.     }
  794.  
  795.     W3D_SetState(context->w3dContext, W3D_ZBUFFER, W3D_DISABLE);
  796.     W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_ENABLE);
  797.     W3D_SetZCompareMode(context->w3dContext, W3D_Z_LESS);
  798.  
  799.     EraseRect(context->w3dWindow->RPort, context->w3dWindow->BorderLeft,
  800.         context->w3dWindow->BorderTop,
  801.         context->w3dWindow->Width-context->w3dWindow->BorderLeft-context->w3dWindow->BorderRight-1,
  802.         context->w3dWindow->Height-context->w3dWindow->BorderTop-context->w3dWindow->BorderBottom-1);
  803.  
  804.     GLScissor(context, 0,0, w,h);
  805.  
  806.     context->w3dLocked = GL_FALSE;
  807.  
  808.     /*
  809.     ** Select a texture format that needs no conversion
  810.     */
  811.     //FIXME:Really do it. This is lame
  812.     context->w3dFormat = W3D_R5G6B5;
  813.     context->w3dAlphaFormat = W3D_A4R4G4B4;
  814.     context->w3dBytesPerTexel = 2;
  815.  
  816.     return GL_TRUE;
  817.  
  818. Duh:
  819.     if (context->w3dWindow)
  820.     {
  821.         CloseWindow(context->w3dWindow);
  822.         context->w3dWindow = NULL;
  823.     }
  824.  
  825.     if (context->w3dScreen)
  826.     {
  827.         UnlockPubScreen(NULL, context->w3dScreen);
  828.         context->w3dScreen = NULL;
  829.     }
  830.  
  831.     if (context->w3dBitMap)
  832.     {
  833.         FreeBitMap(context->w3dBitMap);
  834.     }
  835.  
  836.     if (context->w3dRastPort)
  837.     {
  838.         free(context->w3dRastPort);
  839.     }
  840.  
  841.     return GL_FALSE;
  842. }
  843.  
  844.  
  845. void MGLResizeContext(GLcontext context, GLsizei width, GLsizei height)
  846. {
  847.     if (!context->w3dBitMap)
  848.     {
  849.         vid_ReopenDisplay(context, (int)width, (int)height);
  850.         context->w3dChipID = context->w3dContext->CurrentChip;
  851.     }
  852. }
  853.  
  854. void *MGLGetWindowHandle(GLcontext context)
  855. {
  856.     return context->w3dWindow;
  857. }
  858.  
  859. void mglChooseGuardBand(GLboolean flag)
  860. {
  861.     newGuardBand = flag;
  862. }
  863.  
  864.  
  865. void mglChooseVertexBufferSize(int size)
  866. {
  867.     newVertexBufferSize = size;
  868. }
  869.  
  870. void mglChooseTextureBufferSize(int size)
  871. {
  872.     newTextureBufferSize = size;
  873. }
  874.  
  875. void mglChooseNumberOfBuffers(int number)
  876. {
  877.     newNumberOfBuffers = number;
  878. }
  879.  
  880. void mglChoosePixelDepth(int depth)
  881. {
  882.     newPixelDepth = depth;
  883. }
  884.  
  885. void mglProposeCloseDesktop(GLboolean closeme)
  886. {
  887.     clw = closeme;
  888. }
  889.  
  890. void mglProhibitMipMapping(GLboolean flag)
  891. {
  892.     newNoMipMapping = flag;
  893. }
  894.  
  895. void mglProhibitAlphaFallback(GLboolean flag)
  896. {
  897.     newNoFallbackAlpha = flag;
  898. }
  899.  
  900. void mglChooseWindowMode(GLboolean flag)
  901. {
  902.     newWindowMode = flag;
  903. }
  904.  
  905.  
  906. void GLClearColor(GLcontext context, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
  907. {
  908.     //LOG(2, glClearColor, "%f %f %f %f", red,green,blue,alpha);
  909.  
  910.     red *= 255.0;
  911.     green *= 255.0;
  912.     blue *= 255.0;
  913.     alpha *= 255.0;
  914.  
  915.     context->ClearColor = ((GLubyte)(alpha)<<24)
  916.                         + ((GLubyte)(red)<<16)
  917.                         + ((GLubyte)(green)<<8)
  918.                         + ((GLubyte)(blue));
  919. }
  920.  
  921. void GLDepthMask(GLcontext context, GLboolean flag)
  922. {
  923.     //LOG(2, glDepthMask, "%d", flag);
  924.     if (flag == GL_FALSE)
  925.         W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_DISABLE);
  926.     else
  927.         W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_ENABLE);
  928.  
  929.     context->DepthMask = flag;
  930. }
  931.  
  932. void GLDepthFunc(GLcontext context, GLenum func)
  933. {
  934.     ULONG wFunc = W3D_Z_LESS;
  935.     //LOG(2, glDepthFunc, "%d", func);
  936.     switch(func)
  937.     {
  938.         case GL_NEVER:      wFunc = W3D_Z_NEVER; break;
  939.         case GL_LESS:       wFunc = W3D_Z_LESS; break;
  940.         case GL_EQUAL:      wFunc = W3D_Z_EQUAL; break;
  941.         case GL_LEQUAL:     wFunc = W3D_Z_LEQUAL; break;
  942.         case GL_GREATER:    wFunc = W3D_Z_GREATER; break;
  943.         case GL_NOTEQUAL:   wFunc = W3D_Z_NOTEQUAL; break;
  944.         case GL_GEQUAL:     wFunc = W3D_Z_GEQUAL; break;
  945.         case GL_ALWAYS:     wFunc = W3D_Z_ALWAYS; break;
  946.         default:
  947.             GLFlagError(context, 1, GL_INVALID_ENUM);
  948.             break;
  949.     }
  950.     W3D_SetZCompareMode(context->w3dContext, wFunc);
  951. }
  952.  
  953.  
  954. void GLClearDepth(GLcontext context, GLclampd depth)
  955. {
  956.     //LOG(2, glClearDepth, "%f", depth);
  957.     context->ClearDepth = (W3D_Double)depth;
  958. }
  959.  
  960. void GLClear(GLcontext context, GLbitfield mask)
  961. {
  962.     //LOG(1, glClear, "%d", mask);
  963.     if (context->w3dLocked == GL_FALSE)
  964.         W3D_LockHardware(context->w3dContext);
  965.  
  966.     if (mask & GL_COLOR_BUFFER_BIT)
  967.     {
  968.         W3D_ClearDrawRegion(context->w3dContext, context->ClearColor);
  969.     }
  970.  
  971.  
  972.     if (mask & GL_DEPTH_BUFFER_BIT)
  973.     {
  974.         W3D_ClearZBuffer(context->w3dContext, &(context->ClearDepth));
  975.     }
  976.  
  977.  
  978.     if (context->w3dLocked == GL_FALSE)
  979.         W3D_UnLockHardware(context->w3dContext);
  980. }
  981.  
  982. void MGLLockMode(GLcontext context, GLenum lockMode)
  983. {
  984. #ifdef AUTOMATIC_LOCKING_ENABLE
  985.     context->LockMode = lockMode;
  986. #endif
  987. }
  988.  
  989. GLboolean MGLLockBack(GLcontext context, MGLLockInfo *info)
  990. {
  991.     ULONG error;
  992.     
  993.     if (context->w3dLocked == GL_TRUE)
  994.     {
  995.         error = W3D_SUCCESS;
  996.     }
  997.     else
  998.     {
  999.         error = W3D_LockHardware(context->w3dContext);
  1000.     }
  1001.  
  1002.     if (error != W3D_SUCCESS)
  1003.     {
  1004.         return GL_FALSE;
  1005.     }
  1006. #ifdef AUTOMATIC_LOCKING_ENABLE //surgeon
  1007.     else
  1008.     {
  1009.         context->w3dLocked = GL_TRUE;
  1010.         TMA_Start(&(context->LockTime));
  1011.         if (info)
  1012.         {
  1013.             info->width = context->w3dContext->width;
  1014.             info->height = context->w3dContext->height;
  1015.             info->depth = context->w3dContext->depth;
  1016.             info->pixel_format = context->w3dContext->format;
  1017.             info->base_address = context->w3dContext->drawmem;
  1018.             info->pitch = context->w3dContext->bprow;
  1019.         }
  1020.     }
  1021. #endif
  1022.     return GL_TRUE;
  1023. }
  1024.  
  1025. GLboolean MGLLockDisplay(GLcontext context)
  1026. {
  1027.     ULONG error;
  1028.     //LOG(1, mglLockDisplay, "");
  1029. #ifndef AUTOMATIC_LOCKING_ENABLE
  1030.     if (context->w3dLocked == GL_TRUE) return GL_TRUE;
  1031.  
  1032.     error = W3D_LockHardware(context->w3dContext);
  1033.  
  1034.     if (error == W3D_SUCCESS)
  1035.     {
  1036.         context->w3dLocked = GL_TRUE;
  1037.         return GL_TRUE;
  1038.     }
  1039.     else
  1040.     {
  1041.         switch(error)
  1042.         {
  1043.             case W3D_NOTVISIBLE: printf("[MGLLockDisplay] Bitmap not visible\n"); break;
  1044.             default: printf("[MGLLockDisplay] Error %d while locking\n", error); break;
  1045.         }
  1046.         return GL_FALSE;
  1047.     }
  1048. #else
  1049.     if (context->w3dLocked == GL_TRUE) return GL_TRUE; // nothing to do if we are already locked
  1050.  
  1051.     switch(context->LockMode)
  1052.     {
  1053.         case MGL_LOCK_MANUAL:
  1054.             error = W3D_LockHardware(context->w3dContext);
  1055.             if (error == W3D_SUCCESS)
  1056.             {
  1057.                 context->w3dLocked = GL_TRUE;
  1058.                 return GL_TRUE;
  1059.             }
  1060.             break;
  1061.         case MGL_LOCK_AUTOMATIC: // These modes do not require the lock right here.
  1062.         case MGL_LOCK_SMART:
  1063.             return GL_TRUE;
  1064.             break;
  1065.     }
  1066.     printf("[MGLLockDisplay] Unable to lock\n");
  1067.     return GL_FALSE;            // If we got here, there was an error
  1068. #endif
  1069. }
  1070.  
  1071. void MGLUnlockDisplay(GLcontext context)
  1072. {
  1073.     //LOG(1, mglUnlockDisplay, "");
  1074. #ifndef AUTOMATIC_LOCKING_ENABLE
  1075.     if (context->w3dLocked == GL_FALSE) return;
  1076.     W3D_UnLockHardware(context->w3dContext);
  1077.     context->w3dLocked = GL_FALSE;
  1078. #else
  1079.     if (context->w3dLocked == GL_FALSE) return;
  1080.     switch(context->LockMode)
  1081.     {
  1082.         case MGL_LOCK_AUTOMATIC:
  1083.             break;
  1084.         case MGL_LOCK_SMART:
  1085.         case MGL_LOCK_MANUAL:
  1086.             W3D_UnLockHardware(context->w3dContext);
  1087.             break;
  1088.     }
  1089.     context->w3dLocked = GL_FALSE;
  1090. #endif
  1091. }
  1092.  
  1093. void MGLEnableSync(GLcontext context, GLboolean enable)
  1094. {
  1095.     context->DoSync = enable;
  1096. }
  1097.  
  1098. void MGLSwitchDisplay(GLcontext context)
  1099. {
  1100.     int nowbuf = context->BufNr;
  1101.  
  1102.     MGLUnlockDisplay(context);
  1103.     
  1104.     if (!context->w3dBitMap) // Fullscreen mode
  1105.     {
  1106.         context->BufNr++;
  1107.         if (context->BufNr == context->NumBuffers)
  1108.             context->BufNr = 0;
  1109.  
  1110.         /*
  1111.         ** At this place, nowbuf contains the buffer we where drawing to.
  1112.         ** BufNr is the next drawing buffer.
  1113.         ** We switch nowbof to the be the display buffer, and set
  1114.         ** the draw region to the new BufNr
  1115.         */
  1116.  
  1117.         // FIXME: This may cause a context switch orgy, maybe make it 68k
  1118.         // Make nowbuf current display
  1119.         context->Buffers[nowbuf]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
  1120.         while (!ChangeScreenBuffer(context->w3dScreen, context->Buffers[nowbuf]));
  1121.  
  1122.         // Make BufNr the new draw area
  1123.  
  1124.         W3D_SetDrawRegion(context->w3dContext, context->Buffers[context->BufNr]->sb_BitMap,
  1125.             0, &(context->scissor));
  1126.     
  1127.         if (context->DoSync)
  1128.         {
  1129.             struct ViewPort *vp = &(context->w3dScreen->ViewPort);
  1130.             WaitBOVP(vp);
  1131.         }
  1132.     }
  1133.     else
  1134.     {   // Windowed mode
  1135.         ClipBlit(context->w3dRastPort,0,0,
  1136.             context->w3dWindow->RPort, context->w3dWindow->BorderLeft,
  1137.             context->w3dWindow->BorderTop,
  1138.             context->w3dWindow->Width-context->w3dWindow->BorderLeft-context->w3dWindow->BorderRight,
  1139.             context->w3dWindow->Height-context->w3dWindow->BorderTop-context->w3dWindow->BorderBottom,
  1140.             0xC0);
  1141.     }
  1142. }
  1143.  
  1144.  
  1145.  
  1146. //Multitexture buffer:
  1147.  
  1148. extern void FreeMtex();
  1149. extern GLboolean AllocMtex();
  1150.  
  1151. GLboolean MGLInitContext(GLcontext context)
  1152. {
  1153.     int i;
  1154.  
  1155.     context->CurrentPrimitive   = GL_BASE;
  1156.     context->CurrentError       = GL_NO_ERROR;
  1157.  
  1158. /*
  1159. allocate w array that is large enough to cope with almost any texcoordstride - this array is used for all textured, unclipped primitives that go theough the vetexarray pipeline
  1160. */
  1161.  
  1162.     context->WBuffer        =
  1163. malloc(64*newVertexBufferSize);
  1164.     if (!context->WBuffer)
  1165.         return GL_FALSE;
  1166.  
  1167.     //this is for glArrayElement and for glDrawElements index-conversion:
  1168.  
  1169.     context->ElementIndex        =
  1170. malloc(sizeof(UWORD)*(newVertexBufferSize));
  1171.  
  1172.     if (!context->ElementIndex)
  1173.         return GL_FALSE;
  1174.  
  1175.     context->VertexBuffer       = malloc(sizeof(MGLVertex)*newVertexBufferSize);
  1176.     if (!context->VertexBuffer)
  1177.         return GL_FALSE;
  1178.  
  1179.     context->NormalBuffer       = malloc(sizeof(MGLNormal)*newVertexBufferSize);
  1180.     if (!context->NormalBuffer)
  1181.         return GL_FALSE;
  1182.  
  1183.     context->VertexBufferSize   = (GLuint)newVertexBufferSize;
  1184.     context->VertexBufferPointer = 0;
  1185.  
  1186.     //GL_MGL_ARB_multitexture: draw.c
  1187.     if(!AllocMtex())
  1188.         return GL_FALSE;
  1189.  
  1190.  
  1191.     context->NormalBufferPointer = 0;
  1192.  
  1193.     context->NormalBuffer[0].x = 0.f;
  1194.     context->NormalBuffer[0].y = 0.f;
  1195.     context->NormalBuffer[0].z = 0.f;
  1196.  
  1197.  
  1198.     context->TexBufferSize      = newTextureBufferSize;
  1199.     context->w3dTexBuffer       = malloc(sizeof(W3D_Texture *) * newTextureBufferSize);
  1200.     context->GeneratedTextures  = malloc(sizeof(GLubyte) * newTextureBufferSize);
  1201.  
  1202.     if (!context->w3dTexBuffer || !context->GeneratedTextures)
  1203.         return GL_FALSE;
  1204.  
  1205.  
  1206.     context->w3dTexMemory       = malloc(sizeof(GLubyte *) * newTextureBufferSize);
  1207.     if (!context->w3dTexMemory)
  1208.         return GL_FALSE;
  1209.  
  1210.     // Indicate unbound texture object(s):
  1211.  
  1212.     context->CurrentBinding  = 0;
  1213.     context->VirtualBinding  = 0;
  1214.     context->ArrayTexBound     = GL_FALSE; //repeated by glEnd();
  1215.  
  1216.     context->ActiveTexture   = 0;
  1217.     context->VirtualTexUnits = 0;  //disable multitex
  1218.  
  1219.     for (i=0; i<newTextureBufferSize; i++)
  1220.     {
  1221.         context->w3dTexBuffer[i]    = NULL;
  1222.         context->w3dTexMemory[i]    = NULL;
  1223.         context->GeneratedTextures[i]   = 0;
  1224.     }
  1225.  
  1226.     context->CurrentTexS = context->CurrentTexT = 0.0;
  1227.     context->CurrentTexQ = 1.0;
  1228.     context->CurrentTexQValid = GL_FALSE;
  1229.  
  1230.     context->PackAlign = context->UnpackAlign = 4;
  1231.  
  1232.     context->AlphaTest_State    = GL_FALSE;
  1233.     context->Blend_State        = GL_FALSE;
  1234.     context->TextureGenS_State  = GL_FALSE;
  1235.     context->TextureGenT_State  = GL_FALSE;
  1236.     context->Fog_State          = GL_FALSE;
  1237.     context->Scissor_State      = GL_FALSE;
  1238.     context->CullFace_State     = GL_FALSE;
  1239.     context->DepthTest_State    = GL_FALSE;
  1240.     context->PointSmooth_State  = GL_FALSE;
  1241.     context->Dither_State       = GL_TRUE;
  1242.     context->ZOffset_State      = GL_FALSE;
  1243.  
  1244.     context->FogDirty           = GL_FALSE;
  1245.     context->FogStart           = 1.0;
  1246.     context->FogEnd             = 0.0;
  1247.  
  1248.     for (i=0; i<MAX_TEXUNIT; i++)
  1249.     {
  1250.         context->Texture2D_State[i]    = GL_FALSE;
  1251.         context->TexEnv[i]        = GL_MODULATE;
  1252.     }
  1253.  
  1254.  
  1255.     context->CurTexEnv = 0;
  1256.  
  1257.     context->MinFilter = GL_NEAREST;
  1258.     context->MagFilter = GL_NEAREST;
  1259.     context->WrapS     = GL_REPEAT;
  1260.     context->WrapT     = GL_REPEAT;
  1261.  
  1262.     context->w3dFog.fog_start   = 1.0;
  1263.     context->w3dFog.fog_end     = 0.1;
  1264.     context->w3dFog.fog_density = 1.0;
  1265.     context->w3dFog.fog_color.r = 0.0;
  1266.     context->w3dFog.fog_color.g = 0.0;
  1267.     context->w3dFog.fog_color.b = 0.0;
  1268.     context->FogRange           = 1.0;
  1269.  
  1270.     context->CurrentCullFace    = GL_BACK;
  1271.     context->CurrentFrontFace   = GL_CCW;
  1272.     context->CurrentCullSign    = 1;
  1273. //Surgeon begin
  1274.     context->CurrentColor.r = 1.0;
  1275.     context->CurrentColor.g = 1.0;
  1276.     context->CurrentColor.b = 1.0;
  1277.     context->CurrentColor.a = 1.0;
  1278.     context->UpdateCurrentColor = GL_TRUE;
  1279. //Surgeon end
  1280.  
  1281.     context->ShadeModel         = GL_SMOOTH;
  1282.     context->DepthMask          = GL_TRUE;
  1283.  
  1284.     context->ClearDepth         = 1.0;
  1285.  
  1286. #ifdef AUTOMATIC_LOCKING_ENABLE
  1287.     context->LockMode = MGL_LOCK_MANUAL;
  1288. #endif
  1289.  
  1290.     context->NoMipMapping = newNoMipMapping;
  1291.     context->NoFallbackAlpha = newNoFallbackAlpha;
  1292.  
  1293.     context->Idle = NULL;
  1294.     context->MouseHandler = NULL;
  1295.     context->SpecialHandler = NULL;
  1296.     context->KeyHandler = NULL;
  1297.  
  1298.     context->SrcAlpha = 0;
  1299.     context->DstAlpha = 0;
  1300.     context->AlphaFellBack = GL_FALSE;
  1301.  
  1302.     context->WOne_Hint = GL_FALSE;
  1303.     context->FixpointTrans_Hint = GL_FALSE; //Surgeon
  1304.  
  1305.     context->ZOffset = 0.0;
  1306.  
  1307.     context->PaletteData = malloc(4*256);
  1308.     context->PaletteSize = 0;
  1309.     context->PaletteFormat = 0;
  1310.  
  1311. /* Begin Joe Sera Sept 23 2000 */
  1312.     context->CurPolygonMode      = GL_FILL ;
  1313.     context->CurShadeModel       = GL_SMOOTH ;
  1314.     context->CurBlendSrc         = GL_ONE ;
  1315.     context->CurBlendDst         = GL_ZERO ;
  1316.     context->CurUnpackRowLength  = 0 ;
  1317.     context->CurUnpackSkipPixels = 0 ;
  1318.     context->CurUnpackSkipRows   = 0 ;
  1319. /* End Joe Sera Sept 23 2000 */
  1320.  
  1321. /* Begin Joe Sera Oct. 21, 2000 */
  1322.     context->CurWriteMask = GL_TRUE ;
  1323.     context->CurDepthTest = GL_FALSE ;
  1324. /* End Joe Sera Oct. 21, 2000 */
  1325.  
  1326.     /* Vertex array stuff */
  1327.     context->ClientState        = 0;
  1328. #if 0
  1329.     context->DrawElementsHook   = 0;
  1330.     context->DrawArraysHook     = 0;
  1331. #endif
  1332.     context->VertexArrayPipeline  = GL_TRUE;
  1333.  
  1334. //Surgeon:
  1335.     context->ArrayTexBound = GL_FALSE;
  1336.  
  1337.     context->ArrayPointer.colors = (UBYTE *)&context->VertexBuffer->color;
  1338.     context->ArrayPointer.colorstride = sizeof(MGLVertex);
  1339.     context->ArrayPointer.colormode = W3D_COLOR_UBYTE | W3D_CMODE_RGBA; //type and size
  1340.  
  1341.     context->ArrayPointer.texcoords = (UBYTE *)&context->VertexBuffer->v.u;
  1342.     context->ArrayPointer.texcoordstride = sizeof(MGLVertex);
  1343.     context->ArrayPointer.w_off = -4;
  1344.  
  1345.     context->ArrayPointer.verts = (UBYTE *)&context->VertexBuffer->v.x;
  1346.     context->ArrayPointer.vertexstride = sizeof(MGLVertex);
  1347.     context->ArrayPointer.vertexmode = W3D_VERTEX_F_F_D;
  1348.  
  1349.     context->ArrayPointer.transformed = GL_FALSE;
  1350.     context->ArrayPointer.lockfirst = 0;
  1351.     context->ArrayPointer.locksize = 0;
  1352.     context->ArrayPointer.FixpointTrans = GL_FALSE;
  1353.  
  1354.     /* Area: All triangles smaller than this will not be drawn */
  1355.     //Surgeon: to prevent gaps, triangle-mesh areas are considered coherently
  1356.  
  1357.     context->MinTriArea         = 0.5f;
  1358.  
  1359.     context->CurrentPointSize     = 1.f;
  1360.  
  1361.     //We set all clipflags by default:
  1362.  
  1363.     context->ClipFlags = (MGL_CLIP_NEGW | MGL_CLIP_FRONT | MGL_CLIP_BACK | MGL_CLIP_RIGHT | MGL_CLIP_LEFT | MGL_CLIP_BOTTOM | MGL_CLIP_TOP);
  1364.  
  1365.     //The 3 first are 'must' clipflags.
  1366.     //The 4 last are set by glViewport, according to
  1367.     //state of guardband clipping
  1368.  
  1369.     context->GuardBand        = newGuardBand;
  1370.  
  1371.     GLMatrixInit(context);
  1372.  
  1373.     return GL_TRUE;
  1374. }
  1375.  
  1376. void *MGLCreateContext(int offx, int offy, int w, int h)
  1377. {
  1378.     GLcontext context;
  1379.  
  1380.     context = malloc(sizeof(struct GLcontext_t));
  1381.     if (!context)
  1382.     {
  1383. //        printf("Error: Can't get %d bytes of memory for context\n", sizeof(struct GLcontext_t));
  1384.         printf("Error: Can't get %lu bytes of memory for context\n", sizeof(struct GLcontext_t)); //OF
  1385.  
  1386.         return NULL;
  1387.     }
  1388.  
  1389.     memset(context, 0,  sizeof(struct GLcontext_t));
  1390.  
  1391.     if (newWindowMode == GL_FALSE)
  1392.     {
  1393.         if (GL_FALSE == vid_OpenDisplay(context, w,h, MGL_SM_BESTMODE))
  1394.         {
  1395.             vid_CloseDisplay(context);
  1396.             free(context);
  1397.             printf("Error: opening of display failed\n");
  1398.             return NULL;
  1399.         }
  1400.     }
  1401.     else
  1402.     {
  1403.         if (GL_FALSE == vid_OpenWindow(context, w,h))
  1404.         {
  1405.             vid_CloseWindow(context);
  1406.             free(context);
  1407.             printf("Error: opening of display failed\n");
  1408.             return NULL;
  1409.         }
  1410.     }
  1411.  
  1412.     if (GL_FALSE == MGLInitContext(context))
  1413.     {
  1414.         printf("Error: initalisation of context failed\n");
  1415.         MGLDeleteContext(context);
  1416.         return NULL;
  1417.     }
  1418.  
  1419.     GLDepthRange(context, 0.0, 1.0);
  1420.     GLViewport(context, offx, offy, w, h);
  1421.     GLClearColor(context, 1.0, 1.0, 1.0, 1.0);
  1422.  
  1423.     // Hey, folks, I can do that because I know what I am doing.
  1424.     // You should never read fields from the W3D context that are not
  1425.     // marked as readable...
  1426.     context->w3dChipID = context->w3dContext->CurrentChip;
  1427.  
  1428.     return context;
  1429. }
  1430.  
  1431.  
  1432. void MGLDeleteContext(GLcontext context)
  1433. {
  1434.     GLint current,peak;
  1435.  
  1436.     if( !context ) return; //Olivier Fabre
  1437.  
  1438.     if (context->w3dBitMap) vid_CloseWindow(context);
  1439.     else                    vid_CloseDisplay(context);
  1440.  
  1441.     FreeMtex();
  1442.  
  1443.     if (context->NormalBuffer) free(context->NormalBuffer);
  1444.  
  1445.     if (context->WBuffer) free(context->WBuffer);
  1446.  
  1447.     if (context->ElementIndex) free(context->ElementIndex);
  1448.  
  1449.     if (context->VertexBuffer) free(context->VertexBuffer);
  1450.  
  1451.     if (context->w3dTexBuffer) free(context->w3dTexBuffer);
  1452.  
  1453.     if (context->GeneratedTextures) free (context->GeneratedTextures);
  1454.  
  1455.     MGLTexMemStat(context, ¤t, &peak);
  1456.  
  1457.     if (CyberGfxBase) CloseLibrary(CyberGfxBase);
  1458.     CyberGfxBase = NULL;
  1459.  
  1460.     free(context);
  1461. }
  1462.  
  1463. #define ED (flag == GL_TRUE?W3D_ENABLE:W3D_DISABLE)
  1464.  
  1465. extern void tex_SetEnv(GLcontext context, GLenum env);
  1466.  
  1467. void MGLSetState(GLcontext context, const GLenum cap, const GLboolean flag)//surgeon: const
  1468. {
  1469.     int active = context->ActiveTexture;
  1470.  
  1471.     //LOG(2, mglSetState, "(Enable/Disable) %d -> %d\n", cap, flag);
  1472.  
  1473.     switch(cap)
  1474.     {
  1475.         case GL_ALPHA_TEST:
  1476.             //surgeon: added state-check
  1477.             if(context->AlphaTest_State != flag)
  1478.             {
  1479.             context->AlphaTest_State = flag;
  1480.             W3D_SetState(context->w3dContext, W3D_ALPHATEST, ED);
  1481.             }
  1482.         break;
  1483.         case GL_BLEND:
  1484.             //surgeon: added state-check
  1485.             if(context->Blend_State != flag)
  1486.             {
  1487.             context->Blend_State = flag;
  1488.             W3D_SetState(context->w3dContext, W3D_BLENDING, ED);
  1489.             }
  1490.         break;
  1491.         case GL_TEXTURE_2D:
  1492.  
  1493.             if(active == 0 && context->Texture2D_State[0] != flag)
  1494.             {
  1495.                   W3D_SetState(context->w3dContext, W3D_TEXMAPPING, ED);
  1496.             }
  1497.  
  1498.             context->Texture2D_State[active] = flag;
  1499.  
  1500.         break;
  1501.         case GL_TEXTURE_GEN_S:
  1502.             context->TextureGenS_State = flag;
  1503.             break;
  1504.         case GL_TEXTURE_GEN_T:
  1505.             context->TextureGenT_State = flag;
  1506.             break;
  1507.         case GL_FOG:
  1508.             context->FogDirty = GL_TRUE;
  1509.             context->Fog_State = flag;
  1510.             W3D_SetState(context->w3dContext, W3D_FOGGING, ED);
  1511.             break;
  1512.         case GL_SCISSOR_TEST:
  1513.             context->Scissor_State = flag;
  1514.             if(flag == GL_FALSE) //restore
  1515.             W3D_SetScissor(context->w3dContext, &(context->scissor));
  1516.             break;
  1517.         case GL_CULL_FACE:
  1518.             context->CullFace_State = flag;
  1519.  
  1520.             break;
  1521.         case GL_DEPTH_WRITEMASK:
  1522.             context->CurWriteMask = flag ;
  1523.         break ;
  1524.         case GL_DEPTH_TEST:
  1525.             context->CurDepthTest = flag ;
  1526.             context->DepthTest_State = flag;
  1527.  
  1528.             W3D_SetState(context->w3dContext, W3D_ZBUFFER, ED);
  1529.             if (flag == GL_TRUE)
  1530.             {
  1531.                 if (context->DepthMask)
  1532.                     W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_ENABLE);
  1533.             }
  1534.             else
  1535.             {
  1536.                 W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_DISABLE);
  1537.             }
  1538.  
  1539.             break;
  1540.         case GL_DITHER:
  1541.             context->Dither_State = flag;
  1542.             W3D_SetState(context->w3dContext, W3D_DITHERING, ED);
  1543.             break;
  1544.         case GL_POINT_SMOOTH:
  1545.             context->PointSmooth_State = flag;
  1546.             W3D_SetState(context->w3dContext, W3D_ANTI_POINT, ED);
  1547.             break;
  1548.         case MGL_PERSPECTIVE_MAPPING:
  1549.             W3D_SetState(context->w3dContext, W3D_PERSPECTIVE, ED);
  1550.             break;
  1551.         case MGL_Z_OFFSET:
  1552.             context->ZOffset_State = flag;
  1553.             break;
  1554.         case MGL_ARRAY_TRANSFORMATIONS:
  1555.             context->VertexArrayPipeline = flag;
  1556.             break;
  1557.         default:
  1558.             break;
  1559.     }
  1560. }
  1561. #undef ED
  1562.  
  1563. GLint mglGetSupportedScreenModes(MGLScreenModeCallback CallbackFn)
  1564. {
  1565.     W3D_ScreenMode *Modes = W3D_GetScreenmodeList();
  1566.     W3D_ScreenMode *Cursor;
  1567.     MGLScreenMode   sMode;
  1568.     GLboolean       retval;
  1569.  
  1570.     if (Modes == NULL)
  1571.     {
  1572.         return MGL_SM_BESTMODE;
  1573.     }
  1574.  
  1575.     Cursor = Modes;
  1576.     while (Cursor)
  1577.     {
  1578.         sMode.id        = (GLint)Cursor->ModeID;
  1579.         sMode.width     = (GLint)Cursor->Width;
  1580.         sMode.height    = (GLint)Cursor->Height;
  1581.         sMode.bit_depth = (GLint)Cursor->Depth;
  1582.         strncpy(sMode.mode_name, Cursor->DisplayName, MGL_MAX_MODE);
  1583.         retval = CallbackFn(&sMode);
  1584.         if (retval == GL_TRUE)
  1585.         {
  1586.             W3D_FreeScreenmodeList(Modes);
  1587.             return sMode.id;
  1588.         }
  1589.         Cursor = Cursor->Next;
  1590.     }
  1591.     W3D_FreeScreenmodeList(Modes);
  1592.     return MGL_SM_BESTMODE;
  1593. }
  1594.  
  1595. void *MGLCreateContextFromID(GLint id, GLint *width, GLint *height)
  1596. {
  1597.     GLint w,h;
  1598.     GLcontext context;
  1599.  
  1600.     context = malloc(sizeof(struct GLcontext_t));
  1601.     if (!context)
  1602.     {
  1603. //        printf("Error: Can't get %d bytes of memory for context\n", sizeof(struct GLcontext_t));
  1604.         printf("Error: Can't get %lu bytes of memory for context\n", sizeof(struct GLcontext_t)); //OF
  1605.  
  1606.         return NULL;
  1607.     }
  1608.  
  1609.     memset(context, 0, sizeof(struct GLcontext_t));
  1610.  
  1611.     if (id == MGL_SM_WINDOWMODE) newWindowMode = GL_TRUE;
  1612.  
  1613.     if (newWindowMode == GL_FALSE)
  1614.     {
  1615.         if (GL_FALSE == vid_OpenDisplay(context, -1,-1, (ULONG)id))
  1616.         {
  1617.             vid_CloseDisplay(context);
  1618.             free(context);
  1619.             printf("Error: opening of display failed\n");
  1620.             return NULL;
  1621.         }
  1622.     }
  1623.     else
  1624.     {
  1625.         // Use the other context creation function for Windowed mode.
  1626.         return NULL;
  1627.     }
  1628.  
  1629.     if (GL_FALSE == MGLInitContext(context))
  1630.     {
  1631.         printf("Error: initalisation of context failed\n");
  1632.         MGLDeleteContext(context);
  1633.         return NULL;
  1634.     }
  1635.  
  1636.     w = context->w3dScreen->Width;
  1637.     h = context->w3dScreen->Height;
  1638.     *width = w;
  1639.     *height = h;
  1640.  
  1641.     GLDepthRange(context, 0.0, 1.0);
  1642.     GLViewport(context, 0, 0, w, h);
  1643.     GLClearColor(context, 1.0, 1.0, 1.0, 1.0);
  1644.  
  1645.     // Hey, folks, I can do that because I know what I am doing.
  1646.     // You should never read fields from the W3D context that are not
  1647.     // marked as readable...
  1648.     context->w3dChipID = context->w3dContext->CurrentChip;
  1649.  
  1650.     return context;
  1651. }
  1652.  
  1653. void MGLMinTriArea(GLcontext context, GLfloat area)
  1654. {
  1655.     context->MinTriArea = area;
  1656. }
  1657.